{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-05-16T10:04:28.463479Z",
     "start_time": "2025-05-16T10:04:26.780579Z"
    }
   },
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import warnings\n",
    "\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "plt.rcParams['font.family'] = 'SimHei'\n",
    "plt.rcParams['axes.unicode_minus'] = False"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "8f69a190f55f174c"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "1.1 加载原始数据"
   ],
   "id": "30b082cb663ca5f9"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [],
   "id": "2c1ae3fbbecfce34"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-16T10:04:36.125665Z",
     "start_time": "2025-05-16T10:04:35.117906Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# todo P——商品子集，P ⊆ I\n",
    "item_data = pd.read_csv('Data_set/tianchi_fresh_comp_train_item.csv')\n",
    "item_data"
   ],
   "id": "6f44e6083a70aae",
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "[Errno 2] No such file or directory: 'Data_set/tianchi_fresh_comp_train_item.csv'",
     "output_type": "error",
     "traceback": [
      "\u001B[31m---------------------------------------------------------------------------\u001B[39m",
      "\u001B[31mFileNotFoundError\u001B[39m                         Traceback (most recent call last)",
      "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[2]\u001B[39m\u001B[32m, line 2\u001B[39m\n\u001B[32m      1\u001B[39m \u001B[38;5;66;03m# todo P——商品子集，P ⊆ I\u001B[39;00m\n\u001B[32m----> \u001B[39m\u001B[32m2\u001B[39m item_data = pd.read_csv(\u001B[33m'\u001B[39m\u001B[33mData_set/tianchi_fresh_comp_train_item.csv\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m      3\u001B[39m item_data\n",
      "\u001B[36mFile \u001B[39m\u001B[32m~\\.conda\\envs\\Psonalized-products-user\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1026\u001B[39m, in \u001B[36mread_csv\u001B[39m\u001B[34m(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)\u001B[39m\n\u001B[32m   1013\u001B[39m kwds_defaults = _refine_defaults_read(\n\u001B[32m   1014\u001B[39m     dialect,\n\u001B[32m   1015\u001B[39m     delimiter,\n\u001B[32m   (...)\u001B[39m\u001B[32m   1022\u001B[39m     dtype_backend=dtype_backend,\n\u001B[32m   1023\u001B[39m )\n\u001B[32m   1024\u001B[39m kwds.update(kwds_defaults)\n\u001B[32m-> \u001B[39m\u001B[32m1026\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m _read(filepath_or_buffer, kwds)\n",
      "\u001B[36mFile \u001B[39m\u001B[32m~\\.conda\\envs\\Psonalized-products-user\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:620\u001B[39m, in \u001B[36m_read\u001B[39m\u001B[34m(filepath_or_buffer, kwds)\u001B[39m\n\u001B[32m    617\u001B[39m _validate_names(kwds.get(\u001B[33m\"\u001B[39m\u001B[33mnames\u001B[39m\u001B[33m\"\u001B[39m, \u001B[38;5;28;01mNone\u001B[39;00m))\n\u001B[32m    619\u001B[39m \u001B[38;5;66;03m# Create the parser.\u001B[39;00m\n\u001B[32m--> \u001B[39m\u001B[32m620\u001B[39m parser = TextFileReader(filepath_or_buffer, **kwds)\n\u001B[32m    622\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m chunksize \u001B[38;5;129;01mor\u001B[39;00m iterator:\n\u001B[32m    623\u001B[39m     \u001B[38;5;28;01mreturn\u001B[39;00m parser\n",
      "\u001B[36mFile \u001B[39m\u001B[32m~\\.conda\\envs\\Psonalized-products-user\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1620\u001B[39m, in \u001B[36mTextFileReader.__init__\u001B[39m\u001B[34m(self, f, engine, **kwds)\u001B[39m\n\u001B[32m   1617\u001B[39m     \u001B[38;5;28mself\u001B[39m.options[\u001B[33m\"\u001B[39m\u001B[33mhas_index_names\u001B[39m\u001B[33m\"\u001B[39m] = kwds[\u001B[33m\"\u001B[39m\u001B[33mhas_index_names\u001B[39m\u001B[33m\"\u001B[39m]\n\u001B[32m   1619\u001B[39m \u001B[38;5;28mself\u001B[39m.handles: IOHandles | \u001B[38;5;28;01mNone\u001B[39;00m = \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[32m-> \u001B[39m\u001B[32m1620\u001B[39m \u001B[38;5;28mself\u001B[39m._engine = \u001B[38;5;28mself\u001B[39m._make_engine(f, \u001B[38;5;28mself\u001B[39m.engine)\n",
      "\u001B[36mFile \u001B[39m\u001B[32m~\\.conda\\envs\\Psonalized-products-user\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1880\u001B[39m, in \u001B[36mTextFileReader._make_engine\u001B[39m\u001B[34m(self, f, engine)\u001B[39m\n\u001B[32m   1878\u001B[39m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[33m\"\u001B[39m\u001B[33mb\u001B[39m\u001B[33m\"\u001B[39m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m mode:\n\u001B[32m   1879\u001B[39m         mode += \u001B[33m\"\u001B[39m\u001B[33mb\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m-> \u001B[39m\u001B[32m1880\u001B[39m \u001B[38;5;28mself\u001B[39m.handles = get_handle(\n\u001B[32m   1881\u001B[39m     f,\n\u001B[32m   1882\u001B[39m     mode,\n\u001B[32m   1883\u001B[39m     encoding=\u001B[38;5;28mself\u001B[39m.options.get(\u001B[33m\"\u001B[39m\u001B[33mencoding\u001B[39m\u001B[33m\"\u001B[39m, \u001B[38;5;28;01mNone\u001B[39;00m),\n\u001B[32m   1884\u001B[39m     compression=\u001B[38;5;28mself\u001B[39m.options.get(\u001B[33m\"\u001B[39m\u001B[33mcompression\u001B[39m\u001B[33m\"\u001B[39m, \u001B[38;5;28;01mNone\u001B[39;00m),\n\u001B[32m   1885\u001B[39m     memory_map=\u001B[38;5;28mself\u001B[39m.options.get(\u001B[33m\"\u001B[39m\u001B[33mmemory_map\u001B[39m\u001B[33m\"\u001B[39m, \u001B[38;5;28;01mFalse\u001B[39;00m),\n\u001B[32m   1886\u001B[39m     is_text=is_text,\n\u001B[32m   1887\u001B[39m     errors=\u001B[38;5;28mself\u001B[39m.options.get(\u001B[33m\"\u001B[39m\u001B[33mencoding_errors\u001B[39m\u001B[33m\"\u001B[39m, \u001B[33m\"\u001B[39m\u001B[33mstrict\u001B[39m\u001B[33m\"\u001B[39m),\n\u001B[32m   1888\u001B[39m     storage_options=\u001B[38;5;28mself\u001B[39m.options.get(\u001B[33m\"\u001B[39m\u001B[33mstorage_options\u001B[39m\u001B[33m\"\u001B[39m, \u001B[38;5;28;01mNone\u001B[39;00m),\n\u001B[32m   1889\u001B[39m )\n\u001B[32m   1890\u001B[39m \u001B[38;5;28;01massert\u001B[39;00m \u001B[38;5;28mself\u001B[39m.handles \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[32m   1891\u001B[39m f = \u001B[38;5;28mself\u001B[39m.handles.handle\n",
      "\u001B[36mFile \u001B[39m\u001B[32m~\\.conda\\envs\\Psonalized-products-user\\Lib\\site-packages\\pandas\\io\\common.py:873\u001B[39m, in \u001B[36mget_handle\u001B[39m\u001B[34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001B[39m\n\u001B[32m    868\u001B[39m \u001B[38;5;28;01melif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(handle, \u001B[38;5;28mstr\u001B[39m):\n\u001B[32m    869\u001B[39m     \u001B[38;5;66;03m# Check whether the filename is to be opened in binary mode.\u001B[39;00m\n\u001B[32m    870\u001B[39m     \u001B[38;5;66;03m# Binary mode does not support 'encoding' and 'newline'.\u001B[39;00m\n\u001B[32m    871\u001B[39m     \u001B[38;5;28;01mif\u001B[39;00m ioargs.encoding \u001B[38;5;129;01mand\u001B[39;00m \u001B[33m\"\u001B[39m\u001B[33mb\u001B[39m\u001B[33m\"\u001B[39m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m ioargs.mode:\n\u001B[32m    872\u001B[39m         \u001B[38;5;66;03m# Encoding\u001B[39;00m\n\u001B[32m--> \u001B[39m\u001B[32m873\u001B[39m         handle = \u001B[38;5;28mopen\u001B[39m(\n\u001B[32m    874\u001B[39m             handle,\n\u001B[32m    875\u001B[39m             ioargs.mode,\n\u001B[32m    876\u001B[39m             encoding=ioargs.encoding,\n\u001B[32m    877\u001B[39m             errors=errors,\n\u001B[32m    878\u001B[39m             newline=\u001B[33m\"\u001B[39m\u001B[33m\"\u001B[39m,\n\u001B[32m    879\u001B[39m         )\n\u001B[32m    880\u001B[39m     \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m    881\u001B[39m         \u001B[38;5;66;03m# Binary mode\u001B[39;00m\n\u001B[32m    882\u001B[39m         handle = \u001B[38;5;28mopen\u001B[39m(handle, ioargs.mode)\n",
      "\u001B[31mFileNotFoundError\u001B[39m: [Errno 2] No such file or directory: 'Data_set/tianchi_fresh_comp_train_item.csv'"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:06:49.630986Z",
     "start_time": "2025-05-14T01:06:41.592569Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# todo D——用户对商品全集的行为数据集合\n",
    "user_data = pd.read_csv('Data_set/tianchi_fresh_comp_train_user.csv')\n",
    "user_data"
   ],
   "id": "74fb9872412baa5b",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "           user_id    item_id  behavior_type user_geohash  item_category  \\\n",
       "0         10001082  285259775              1      97lk14c           4076   \n",
       "1         10001082    4368907              1          NaN           5503   \n",
       "2         10001082    4368907              1          NaN           5503   \n",
       "3         10001082   53616768              1          NaN           9762   \n",
       "4         10001082  151466952              1          NaN           5232   \n",
       "...            ...        ...            ...          ...            ...   \n",
       "23291022  65341491  259008790              1          NaN          13164   \n",
       "23291023  65341491  336404938              1          NaN          13164   \n",
       "23291024  65341491   52142024              1      95qhbsu           5201   \n",
       "23291025  65341491  250557965              1          NaN          13164   \n",
       "23291026  65341491  300315408              1          NaN           1838   \n",
       "\n",
       "                   time  \n",
       "0         2014-12-08 18  \n",
       "1         2014-12-12 12  \n",
       "2         2014-12-12 12  \n",
       "3         2014-12-02 15  \n",
       "4         2014-12-12 11  \n",
       "...                 ...  \n",
       "23291022  2014-12-03 12  \n",
       "23291023  2014-12-03 12  \n",
       "23291024  2014-12-10 22  \n",
       "23291025  2014-12-03 12  \n",
       "23291026  2014-11-29 08  \n",
       "\n",
       "[23291027 rows x 6 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>behavior_type</th>\n",
       "      <th>user_geohash</th>\n",
       "      <th>item_category</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>10001082</td>\n",
       "      <td>285259775</td>\n",
       "      <td>1</td>\n",
       "      <td>97lk14c</td>\n",
       "      <td>4076</td>\n",
       "      <td>2014-12-08 18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>10001082</td>\n",
       "      <td>4368907</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5503</td>\n",
       "      <td>2014-12-12 12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>10001082</td>\n",
       "      <td>4368907</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5503</td>\n",
       "      <td>2014-12-12 12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>10001082</td>\n",
       "      <td>53616768</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>9762</td>\n",
       "      <td>2014-12-02 15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>10001082</td>\n",
       "      <td>151466952</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>5232</td>\n",
       "      <td>2014-12-12 11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23291022</th>\n",
       "      <td>65341491</td>\n",
       "      <td>259008790</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>13164</td>\n",
       "      <td>2014-12-03 12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23291023</th>\n",
       "      <td>65341491</td>\n",
       "      <td>336404938</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>13164</td>\n",
       "      <td>2014-12-03 12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23291024</th>\n",
       "      <td>65341491</td>\n",
       "      <td>52142024</td>\n",
       "      <td>1</td>\n",
       "      <td>95qhbsu</td>\n",
       "      <td>5201</td>\n",
       "      <td>2014-12-10 22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23291025</th>\n",
       "      <td>65341491</td>\n",
       "      <td>250557965</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>13164</td>\n",
       "      <td>2014-12-03 12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23291026</th>\n",
       "      <td>65341491</td>\n",
       "      <td>300315408</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1838</td>\n",
       "      <td>2014-11-29 08</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>23291027 rows × 6 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 60
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "1.2 数据探索与基本信息"
   ],
   "id": "ac695d8698b15a4c"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:08:24.336294Z",
     "start_time": "2025-05-14T01:08:24.300237Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(\"\\n目标商品数据统计信息：\")\n",
    "display(item_data.describe())\n",
    "\n",
    "print(\"\\n标商品数据信息空值统计：\")\n",
    "display(item_data.isnull().sum())\n"
   ],
   "id": "25b64c1f9150c4f4",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "目标商品数据统计信息：\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "            item_id  item_category\n",
       "count  6.209180e+05  620918.000000\n",
       "mean   2.004351e+08    6970.213167\n",
       "std    1.191648e+08    3479.627372\n",
       "min    9.580000e+02       2.000000\n",
       "25%    9.357641e+07    4245.000000\n",
       "50%    2.053761e+08    6890.000000\n",
       "75%    3.054015e+08   10120.000000\n",
       "max    4.045624e+08   14071.000000"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>item_id</th>\n",
       "      <th>item_category</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>6.209180e+05</td>\n",
       "      <td>620918.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>2.004351e+08</td>\n",
       "      <td>6970.213167</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>1.191648e+08</td>\n",
       "      <td>3479.627372</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>9.580000e+02</td>\n",
       "      <td>2.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>9.357641e+07</td>\n",
       "      <td>4245.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>2.053761e+08</td>\n",
       "      <td>6890.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>3.054015e+08</td>\n",
       "      <td>10120.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>4.045624e+08</td>\n",
       "      <td>14071.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "标商品数据信息空值统计：\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "item_id               0\n",
       "item_geohash     417508\n",
       "item_category         0\n",
       "dtype: int64"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 61
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:08:37.718301Z",
     "start_time": "2025-05-14T01:08:35.205598Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 查看数据基本信息\n",
    "\n",
    "print(\"\\n用户行为数据统计信息：\")\n",
    "display(user_data.describe())\n",
    "\n",
    "print(\"\\n用户行为数据信息空值统计：\")\n",
    "display(user_data.isnull().sum())\n",
    "\n",
    "print(\"\\n行为类型分布：\")\n",
    "display(user_data['behavior_type'].value_counts())"
   ],
   "id": "2a7f1a0b0a7a23e4",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "用户行为数据统计信息：\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "            user_id       item_id  behavior_type  item_category\n",
       "count  2.329103e+07  2.329103e+07   2.329103e+07   2.329103e+07\n",
       "mean   7.006868e+07  2.023214e+08   1.106268e+00   6.835397e+03\n",
       "std    4.569072e+07  1.167440e+08   4.599087e-01   3.812873e+03\n",
       "min    4.920000e+02  3.700000e+01   1.000000e+00   2.000000e+00\n",
       "25%    3.019541e+07  1.014417e+08   1.000000e+00   3.690000e+03\n",
       "50%    5.626942e+07  2.022430e+08   1.000000e+00   6.054000e+03\n",
       "75%    1.166482e+08  3.035325e+08   1.000000e+00   1.027100e+04\n",
       "max    1.424430e+08  4.045625e+08   4.000000e+00   1.408000e+04"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>behavior_type</th>\n",
       "      <th>item_category</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>2.329103e+07</td>\n",
       "      <td>2.329103e+07</td>\n",
       "      <td>2.329103e+07</td>\n",
       "      <td>2.329103e+07</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>7.006868e+07</td>\n",
       "      <td>2.023214e+08</td>\n",
       "      <td>1.106268e+00</td>\n",
       "      <td>6.835397e+03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>4.569072e+07</td>\n",
       "      <td>1.167440e+08</td>\n",
       "      <td>4.599087e-01</td>\n",
       "      <td>3.812873e+03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>4.920000e+02</td>\n",
       "      <td>3.700000e+01</td>\n",
       "      <td>1.000000e+00</td>\n",
       "      <td>2.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>3.019541e+07</td>\n",
       "      <td>1.014417e+08</td>\n",
       "      <td>1.000000e+00</td>\n",
       "      <td>3.690000e+03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>5.626942e+07</td>\n",
       "      <td>2.022430e+08</td>\n",
       "      <td>1.000000e+00</td>\n",
       "      <td>6.054000e+03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>1.166482e+08</td>\n",
       "      <td>3.035325e+08</td>\n",
       "      <td>1.000000e+00</td>\n",
       "      <td>1.027100e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>1.424430e+08</td>\n",
       "      <td>4.045625e+08</td>\n",
       "      <td>4.000000e+00</td>\n",
       "      <td>1.408000e+04</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "用户行为数据信息空值统计：\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "user_id                 0\n",
       "item_id                 0\n",
       "behavior_type           0\n",
       "user_geohash     15911010\n",
       "item_category           0\n",
       "time                    0\n",
       "dtype: int64"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "行为类型分布：\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "behavior_type\n",
       "1    21940520\n",
       "3      659437\n",
       "2      458491\n",
       "4      232579\n",
       "Name: count, dtype: int64"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 62
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "1.3 数据ETL处理"
   ],
   "id": "fceb69db3ec670e4"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:08:51.534425Z",
     "start_time": "2025-05-14T01:08:50.896957Z"
    }
   },
   "cell_type": "code",
   "source": [
    "user_data['user_geohash'].fillna('000000', inplace=True)\n",
    "item_data['item_geohash'].fillna('000000', inplace=True)"
   ],
   "id": "4471ae8d47574930",
   "outputs": [],
   "execution_count": 63
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:10:23.585725Z",
     "start_time": "2025-05-14T01:10:22.173091Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 筛选目标商品的行为数据\n",
    "# 转换时间格式并筛选目标商品\n",
    "user_data['time'] = pd.to_datetime(user_data['time'])\n",
    "user_data['day'] = user_data['time'].dt.day\n",
    "target_item_set = set(item_data['item_id'])\n",
    "\n",
    "user_behavior = user_data[user_data['item_id'].isin(target_item_set)]\n",
    "user_behavior"
   ],
   "id": "67cbc5fded856d73",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "           user_id    item_id  behavior_type user_geohash  item_category  \\\n",
       "13        10001082  275221686              1       000000          10576   \n",
       "14        10001082   97441652              1       000000          10576   \n",
       "15        10001082  275221686              1       000000          10576   \n",
       "16        10001082  275221686              1       000000          10576   \n",
       "24        10001082  125083630              1       000000           4722   \n",
       "...            ...        ...            ...          ...            ...   \n",
       "23290879  65341491  341340328              1       000000           3368   \n",
       "23290902  65341491   15604509              1       000000           3368   \n",
       "23290919  65341491  133486908              1      95qhbs3           3942   \n",
       "23291008  65341491  242501625              1      95qhbs7           3942   \n",
       "23291014  65341491  133486908              1      95qhb09           3942   \n",
       "\n",
       "                        time  day  \n",
       "13       2014-12-03 01:00:00    3  \n",
       "14       2014-11-20 21:00:00   20  \n",
       "15       2014-12-13 14:00:00   13  \n",
       "16       2014-12-08 07:00:00    8  \n",
       "24       2014-12-14 03:00:00   14  \n",
       "...                      ...  ...  \n",
       "23290879 2014-11-19 15:00:00   19  \n",
       "23290902 2014-12-03 17:00:00    3  \n",
       "23290919 2014-12-08 19:00:00    8  \n",
       "23291008 2014-12-08 19:00:00    8  \n",
       "23291014 2014-12-08 19:00:00    8  \n",
       "\n",
       "[2084859 rows x 7 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>behavior_type</th>\n",
       "      <th>user_geohash</th>\n",
       "      <th>item_category</th>\n",
       "      <th>time</th>\n",
       "      <th>day</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>10001082</td>\n",
       "      <td>275221686</td>\n",
       "      <td>1</td>\n",
       "      <td>000000</td>\n",
       "      <td>10576</td>\n",
       "      <td>2014-12-03 01:00:00</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>10001082</td>\n",
       "      <td>97441652</td>\n",
       "      <td>1</td>\n",
       "      <td>000000</td>\n",
       "      <td>10576</td>\n",
       "      <td>2014-11-20 21:00:00</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>10001082</td>\n",
       "      <td>275221686</td>\n",
       "      <td>1</td>\n",
       "      <td>000000</td>\n",
       "      <td>10576</td>\n",
       "      <td>2014-12-13 14:00:00</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>10001082</td>\n",
       "      <td>275221686</td>\n",
       "      <td>1</td>\n",
       "      <td>000000</td>\n",
       "      <td>10576</td>\n",
       "      <td>2014-12-08 07:00:00</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>10001082</td>\n",
       "      <td>125083630</td>\n",
       "      <td>1</td>\n",
       "      <td>000000</td>\n",
       "      <td>4722</td>\n",
       "      <td>2014-12-14 03:00:00</td>\n",
       "      <td>14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23290879</th>\n",
       "      <td>65341491</td>\n",
       "      <td>341340328</td>\n",
       "      <td>1</td>\n",
       "      <td>000000</td>\n",
       "      <td>3368</td>\n",
       "      <td>2014-11-19 15:00:00</td>\n",
       "      <td>19</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23290902</th>\n",
       "      <td>65341491</td>\n",
       "      <td>15604509</td>\n",
       "      <td>1</td>\n",
       "      <td>000000</td>\n",
       "      <td>3368</td>\n",
       "      <td>2014-12-03 17:00:00</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23290919</th>\n",
       "      <td>65341491</td>\n",
       "      <td>133486908</td>\n",
       "      <td>1</td>\n",
       "      <td>95qhbs3</td>\n",
       "      <td>3942</td>\n",
       "      <td>2014-12-08 19:00:00</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23291008</th>\n",
       "      <td>65341491</td>\n",
       "      <td>242501625</td>\n",
       "      <td>1</td>\n",
       "      <td>95qhbs7</td>\n",
       "      <td>3942</td>\n",
       "      <td>2014-12-08 19:00:00</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23291014</th>\n",
       "      <td>65341491</td>\n",
       "      <td>133486908</td>\n",
       "      <td>1</td>\n",
       "      <td>95qhb09</td>\n",
       "      <td>3942</td>\n",
       "      <td>2014-12-08 19:00:00</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>2084859 rows × 7 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 66
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:10:39.091202Z",
     "start_time": "2025-05-14T01:10:38.136852Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 用户特征：用户活跃度和购买转化率\n",
    "user_features = user_behavior.groupby('user_id').agg(\n",
    "    user_total_actions=('behavior_type', 'count'),\n",
    "    user_buy_rate=('behavior_type', lambda x: (x == 4).mean())\n",
    ").reset_index()\n",
    "\n",
    "user_features"
   ],
   "id": "2249c9f31194e417",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "         user_id  user_total_actions  user_buy_rate\n",
       "0            492                  36            0.0\n",
       "1           3726                  27            0.0\n",
       "2          19137                   6            0.0\n",
       "3          36465                  20            0.0\n",
       "4          37101                   1            0.0\n",
       "...          ...                 ...            ...\n",
       "19967  142427508                  85            0.0\n",
       "19968  142432272                   2            0.0\n",
       "19969  142439559                  27            0.0\n",
       "19970  142440276                  45            0.0\n",
       "19971  142442955                  52            0.0\n",
       "\n",
       "[19972 rows x 3 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>user_total_actions</th>\n",
       "      <th>user_buy_rate</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>492</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>3726</td>\n",
       "      <td>27</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>19137</td>\n",
       "      <td>6</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>36465</td>\n",
       "      <td>20</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>37101</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19967</th>\n",
       "      <td>142427508</td>\n",
       "      <td>85</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19968</th>\n",
       "      <td>142432272</td>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19969</th>\n",
       "      <td>142439559</td>\n",
       "      <td>27</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19970</th>\n",
       "      <td>142440276</td>\n",
       "      <td>45</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19971</th>\n",
       "      <td>142442955</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>19972 rows × 3 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 67
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:11:04.927495Z",
     "start_time": "2025-05-14T01:10:45.838530Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 商品特征：商品热度和购买转化率\n",
    "item_features = user_behavior.groupby('item_id').agg(\n",
    "    item_popularity=('behavior_type', 'count'),\n",
    "    item_buy_rate=('behavior_type', lambda x: (x == 4).mean())\n",
    ").reset_index()\n",
    "\n",
    "item_features"
   ],
   "id": "8be8d745278480d6",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "          item_id  item_popularity  item_buy_rate\n",
       "0             958                8            0.0\n",
       "1            1023                3            0.0\n",
       "2            1313                1            0.0\n",
       "3            2213                2            0.0\n",
       "4            2966               14            0.0\n",
       "...           ...              ...            ...\n",
       "422853  404554799                1            0.0\n",
       "422854  404555272                1            0.0\n",
       "422855  404561620                2            0.0\n",
       "422856  404561663               17            0.0\n",
       "422857  404562430                4            0.0\n",
       "\n",
       "[422858 rows x 3 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>item_id</th>\n",
       "      <th>item_popularity</th>\n",
       "      <th>item_buy_rate</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>958</td>\n",
       "      <td>8</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1023</td>\n",
       "      <td>3</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1313</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2213</td>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2966</td>\n",
       "      <td>14</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>422853</th>\n",
       "      <td>404554799</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>422854</th>\n",
       "      <td>404555272</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>422855</th>\n",
       "      <td>404561620</td>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>422856</th>\n",
       "      <td>404561663</td>\n",
       "      <td>17</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>422857</th>\n",
       "      <td>404562430</td>\n",
       "      <td>4</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>422858 rows × 3 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 68
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:13:47.153443Z",
     "start_time": "2025-05-14T01:11:47.949929Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 用户-商品交互特征\n",
    "user_item_inter = user_behavior.groupby(['user_id', 'item_id']).agg(\n",
    "    interact_count=('behavior_type', 'count'),\n",
    "    last_interact_day=('day', 'max'),\n",
    "    has_browsed=('behavior_type', lambda x: (x == 1).any().astype(int)),\n",
    "    has_favorited=('behavior_type', lambda x: (x == 2).any().astype(int)),\n",
    "    has_carted=('behavior_type', lambda x: (x == 3).any().astype(int)),\n",
    "    has_bought=('behavior_type', lambda x: (x == 4).any().astype(int))\n",
    ").reset_index()\n",
    "\n",
    "user_item_inter"
   ],
   "id": "e139543ac8a6ef16",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "          user_id    item_id  interact_count  last_interact_day  has_browsed  \\\n",
       "0             492    2316002               3                  9            1   \n",
       "1             492   31040941               2                 15            1   \n",
       "2             492   50834828               2                  9            1   \n",
       "3             492   65264993               2                  9            1   \n",
       "4             492   76093985               1                 18            1   \n",
       "...           ...        ...             ...                ...          ...   \n",
       "801332  142442955  260934112               2                 15            1   \n",
       "801333  142442955  273532679               2                 15            1   \n",
       "801334  142442955  325938147               3                 15            1   \n",
       "801335  142442955  364397686               2                 15            1   \n",
       "801336  142442955  386680968               2                 15            1   \n",
       "\n",
       "        has_favorited  has_carted  has_bought  \n",
       "0                   0           0           0  \n",
       "1                   0           0           0  \n",
       "2                   0           0           0  \n",
       "3                   0           0           0  \n",
       "4                   0           0           0  \n",
       "...               ...         ...         ...  \n",
       "801332              0           0           0  \n",
       "801333              0           0           0  \n",
       "801334              0           0           0  \n",
       "801335              0           0           0  \n",
       "801336              0           0           0  \n",
       "\n",
       "[801337 rows x 8 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>interact_count</th>\n",
       "      <th>last_interact_day</th>\n",
       "      <th>has_browsed</th>\n",
       "      <th>has_favorited</th>\n",
       "      <th>has_carted</th>\n",
       "      <th>has_bought</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>492</td>\n",
       "      <td>2316002</td>\n",
       "      <td>3</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>492</td>\n",
       "      <td>31040941</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>492</td>\n",
       "      <td>50834828</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>492</td>\n",
       "      <td>65264993</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>492</td>\n",
       "      <td>76093985</td>\n",
       "      <td>1</td>\n",
       "      <td>18</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801332</th>\n",
       "      <td>142442955</td>\n",
       "      <td>260934112</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801333</th>\n",
       "      <td>142442955</td>\n",
       "      <td>273532679</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801334</th>\n",
       "      <td>142442955</td>\n",
       "      <td>325938147</td>\n",
       "      <td>3</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801335</th>\n",
       "      <td>142442955</td>\n",
       "      <td>364397686</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801336</th>\n",
       "      <td>142442955</td>\n",
       "      <td>386680968</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>801337 rows × 8 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 69
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:14:08.908266Z",
     "start_time": "2025-05-14T01:14:08.758963Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 合并所有特征\n",
    "features = user_item_inter.merge(user_features, on='user_id', how='left')\n",
    "features = features.merge(item_features, on='item_id', how='left')\n",
    "features.fillna(0, inplace=True)\n",
    "features"
   ],
   "id": "d2a2b3ca2af36d7",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "          user_id    item_id  interact_count  last_interact_day  has_browsed  \\\n",
       "0             492    2316002               3                  9            1   \n",
       "1             492   31040941               2                 15            1   \n",
       "2             492   50834828               2                  9            1   \n",
       "3             492   65264993               2                  9            1   \n",
       "4             492   76093985               1                 18            1   \n",
       "...           ...        ...             ...                ...          ...   \n",
       "801332  142442955  260934112               2                 15            1   \n",
       "801333  142442955  273532679               2                 15            1   \n",
       "801334  142442955  325938147               3                 15            1   \n",
       "801335  142442955  364397686               2                 15            1   \n",
       "801336  142442955  386680968               2                 15            1   \n",
       "\n",
       "        has_favorited  has_carted  has_bought  user_total_actions  \\\n",
       "0                   0           0           0                  36   \n",
       "1                   0           0           0                  36   \n",
       "2                   0           0           0                  36   \n",
       "3                   0           0           0                  36   \n",
       "4                   0           0           0                  36   \n",
       "...               ...         ...         ...                 ...   \n",
       "801332              0           0           0                  52   \n",
       "801333              0           0           0                  52   \n",
       "801334              0           0           0                  52   \n",
       "801335              0           0           0                  52   \n",
       "801336              0           0           0                  52   \n",
       "\n",
       "        user_buy_rate  item_popularity  item_buy_rate  \n",
       "0                 0.0                3       0.000000  \n",
       "1                 0.0               75       0.013333  \n",
       "2                 0.0                2       0.000000  \n",
       "3                 0.0                2       0.000000  \n",
       "4                 0.0               87       0.000000  \n",
       "...               ...              ...            ...  \n",
       "801332            0.0                2       0.000000  \n",
       "801333            0.0               11       0.000000  \n",
       "801334            0.0               46       0.043478  \n",
       "801335            0.0                5       0.000000  \n",
       "801336            0.0                2       0.000000  \n",
       "\n",
       "[801337 rows x 12 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>interact_count</th>\n",
       "      <th>last_interact_day</th>\n",
       "      <th>has_browsed</th>\n",
       "      <th>has_favorited</th>\n",
       "      <th>has_carted</th>\n",
       "      <th>has_bought</th>\n",
       "      <th>user_total_actions</th>\n",
       "      <th>user_buy_rate</th>\n",
       "      <th>item_popularity</th>\n",
       "      <th>item_buy_rate</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>492</td>\n",
       "      <td>2316002</td>\n",
       "      <td>3</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>492</td>\n",
       "      <td>31040941</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>75</td>\n",
       "      <td>0.013333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>492</td>\n",
       "      <td>50834828</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>492</td>\n",
       "      <td>65264993</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>492</td>\n",
       "      <td>76093985</td>\n",
       "      <td>1</td>\n",
       "      <td>18</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>87</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801332</th>\n",
       "      <td>142442955</td>\n",
       "      <td>260934112</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801333</th>\n",
       "      <td>142442955</td>\n",
       "      <td>273532679</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>11</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801334</th>\n",
       "      <td>142442955</td>\n",
       "      <td>325938147</td>\n",
       "      <td>3</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>46</td>\n",
       "      <td>0.043478</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801335</th>\n",
       "      <td>142442955</td>\n",
       "      <td>364397686</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>5</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801336</th>\n",
       "      <td>142442955</td>\n",
       "      <td>386680968</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>801337 rows × 12 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 70
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:14:21.573916Z",
     "start_time": "2025-05-14T01:14:21.556549Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 添加时间衰减特征\n",
    "max_day = user_behavior['day'].max()\n",
    "features['days_since_last_interact'] = max_day - features['last_interact_day']\n",
    "features['time_decay'] = 1 / (1 + 0.1 * features['days_since_last_interact'])\n",
    "features"
   ],
   "id": "404601229673e62c",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "          user_id    item_id  interact_count  last_interact_day  has_browsed  \\\n",
       "0             492    2316002               3                  9            1   \n",
       "1             492   31040941               2                 15            1   \n",
       "2             492   50834828               2                  9            1   \n",
       "3             492   65264993               2                  9            1   \n",
       "4             492   76093985               1                 18            1   \n",
       "...           ...        ...             ...                ...          ...   \n",
       "801332  142442955  260934112               2                 15            1   \n",
       "801333  142442955  273532679               2                 15            1   \n",
       "801334  142442955  325938147               3                 15            1   \n",
       "801335  142442955  364397686               2                 15            1   \n",
       "801336  142442955  386680968               2                 15            1   \n",
       "\n",
       "        has_favorited  has_carted  has_bought  user_total_actions  \\\n",
       "0                   0           0           0                  36   \n",
       "1                   0           0           0                  36   \n",
       "2                   0           0           0                  36   \n",
       "3                   0           0           0                  36   \n",
       "4                   0           0           0                  36   \n",
       "...               ...         ...         ...                 ...   \n",
       "801332              0           0           0                  52   \n",
       "801333              0           0           0                  52   \n",
       "801334              0           0           0                  52   \n",
       "801335              0           0           0                  52   \n",
       "801336              0           0           0                  52   \n",
       "\n",
       "        user_buy_rate  item_popularity  item_buy_rate  \\\n",
       "0                 0.0                3       0.000000   \n",
       "1                 0.0               75       0.013333   \n",
       "2                 0.0                2       0.000000   \n",
       "3                 0.0                2       0.000000   \n",
       "4                 0.0               87       0.000000   \n",
       "...               ...              ...            ...   \n",
       "801332            0.0                2       0.000000   \n",
       "801333            0.0               11       0.000000   \n",
       "801334            0.0               46       0.043478   \n",
       "801335            0.0                5       0.000000   \n",
       "801336            0.0                2       0.000000   \n",
       "\n",
       "        days_since_last_interact  time_decay  \n",
       "0                             21    0.322581  \n",
       "1                             15    0.400000  \n",
       "2                             21    0.322581  \n",
       "3                             21    0.322581  \n",
       "4                             12    0.454545  \n",
       "...                          ...         ...  \n",
       "801332                        15    0.400000  \n",
       "801333                        15    0.400000  \n",
       "801334                        15    0.400000  \n",
       "801335                        15    0.400000  \n",
       "801336                        15    0.400000  \n",
       "\n",
       "[801337 rows x 14 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>interact_count</th>\n",
       "      <th>last_interact_day</th>\n",
       "      <th>has_browsed</th>\n",
       "      <th>has_favorited</th>\n",
       "      <th>has_carted</th>\n",
       "      <th>has_bought</th>\n",
       "      <th>user_total_actions</th>\n",
       "      <th>user_buy_rate</th>\n",
       "      <th>item_popularity</th>\n",
       "      <th>item_buy_rate</th>\n",
       "      <th>days_since_last_interact</th>\n",
       "      <th>time_decay</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>492</td>\n",
       "      <td>2316002</td>\n",
       "      <td>3</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>21</td>\n",
       "      <td>0.322581</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>492</td>\n",
       "      <td>31040941</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>75</td>\n",
       "      <td>0.013333</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>492</td>\n",
       "      <td>50834828</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>21</td>\n",
       "      <td>0.322581</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>492</td>\n",
       "      <td>65264993</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>21</td>\n",
       "      <td>0.322581</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>492</td>\n",
       "      <td>76093985</td>\n",
       "      <td>1</td>\n",
       "      <td>18</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>87</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>12</td>\n",
       "      <td>0.454545</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801332</th>\n",
       "      <td>142442955</td>\n",
       "      <td>260934112</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801333</th>\n",
       "      <td>142442955</td>\n",
       "      <td>273532679</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>11</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801334</th>\n",
       "      <td>142442955</td>\n",
       "      <td>325938147</td>\n",
       "      <td>3</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>46</td>\n",
       "      <td>0.043478</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801335</th>\n",
       "      <td>142442955</td>\n",
       "      <td>364397686</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>5</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801336</th>\n",
       "      <td>142442955</td>\n",
       "      <td>386680968</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>801337 rows × 14 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 71
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:14:31.626743Z",
     "start_time": "2025-05-14T01:14:31.609553Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 标记正样本（在测试日有购买行为的用户-商品对）\n",
    "test_buys = user_behavior[user_behavior['behavior_type'] == 4]\n",
    "test_buys"
   ],
   "id": "55f14e9f5fc7dac3",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "            user_id    item_id  behavior_type user_geohash  item_category  \\\n",
       "83         10001082  275221686              4       000000          10576   \n",
       "729       100068031   36925766              4      94deoom          10431   \n",
       "910       100068031   97781635              4      9rctoks           4588   \n",
       "980       100068031  217620949              4      94deolj          10431   \n",
       "1090      100068031  254127882              4       000000           9618   \n",
       "...             ...        ...            ...          ...            ...   \n",
       "23276823   65098431  344483839              4      9qumcqd           6648   \n",
       "23276850   65098431  174436835              4      9qumcss           6648   \n",
       "23277199   65113833   31238685              4       000000          12170   \n",
       "23277695   65113833  257213733              4       000000           9232   \n",
       "23283097   65175897  217620750              4      95q5vwh          12630   \n",
       "\n",
       "                        time  day  \n",
       "83       2014-12-02 22:00:00    2  \n",
       "729      2014-12-11 18:00:00   11  \n",
       "910      2014-11-25 23:00:00   25  \n",
       "980      2014-12-11 09:00:00   11  \n",
       "1090     2014-12-11 19:00:00   11  \n",
       "...                      ...  ...  \n",
       "23276823 2014-11-19 23:00:00   19  \n",
       "23276850 2014-11-19 23:00:00   19  \n",
       "23277199 2014-11-27 11:00:00   27  \n",
       "23277695 2014-12-10 11:00:00   10  \n",
       "23283097 2014-12-16 20:00:00   16  \n",
       "\n",
       "[23722 rows x 7 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>behavior_type</th>\n",
       "      <th>user_geohash</th>\n",
       "      <th>item_category</th>\n",
       "      <th>time</th>\n",
       "      <th>day</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>83</th>\n",
       "      <td>10001082</td>\n",
       "      <td>275221686</td>\n",
       "      <td>4</td>\n",
       "      <td>000000</td>\n",
       "      <td>10576</td>\n",
       "      <td>2014-12-02 22:00:00</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>729</th>\n",
       "      <td>100068031</td>\n",
       "      <td>36925766</td>\n",
       "      <td>4</td>\n",
       "      <td>94deoom</td>\n",
       "      <td>10431</td>\n",
       "      <td>2014-12-11 18:00:00</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>910</th>\n",
       "      <td>100068031</td>\n",
       "      <td>97781635</td>\n",
       "      <td>4</td>\n",
       "      <td>9rctoks</td>\n",
       "      <td>4588</td>\n",
       "      <td>2014-11-25 23:00:00</td>\n",
       "      <td>25</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>980</th>\n",
       "      <td>100068031</td>\n",
       "      <td>217620949</td>\n",
       "      <td>4</td>\n",
       "      <td>94deolj</td>\n",
       "      <td>10431</td>\n",
       "      <td>2014-12-11 09:00:00</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1090</th>\n",
       "      <td>100068031</td>\n",
       "      <td>254127882</td>\n",
       "      <td>4</td>\n",
       "      <td>000000</td>\n",
       "      <td>9618</td>\n",
       "      <td>2014-12-11 19:00:00</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23276823</th>\n",
       "      <td>65098431</td>\n",
       "      <td>344483839</td>\n",
       "      <td>4</td>\n",
       "      <td>9qumcqd</td>\n",
       "      <td>6648</td>\n",
       "      <td>2014-11-19 23:00:00</td>\n",
       "      <td>19</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23276850</th>\n",
       "      <td>65098431</td>\n",
       "      <td>174436835</td>\n",
       "      <td>4</td>\n",
       "      <td>9qumcss</td>\n",
       "      <td>6648</td>\n",
       "      <td>2014-11-19 23:00:00</td>\n",
       "      <td>19</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23277199</th>\n",
       "      <td>65113833</td>\n",
       "      <td>31238685</td>\n",
       "      <td>4</td>\n",
       "      <td>000000</td>\n",
       "      <td>12170</td>\n",
       "      <td>2014-11-27 11:00:00</td>\n",
       "      <td>27</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23277695</th>\n",
       "      <td>65113833</td>\n",
       "      <td>257213733</td>\n",
       "      <td>4</td>\n",
       "      <td>000000</td>\n",
       "      <td>9232</td>\n",
       "      <td>2014-12-10 11:00:00</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23283097</th>\n",
       "      <td>65175897</td>\n",
       "      <td>217620750</td>\n",
       "      <td>4</td>\n",
       "      <td>95q5vwh</td>\n",
       "      <td>12630</td>\n",
       "      <td>2014-12-16 20:00:00</td>\n",
       "      <td>16</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>23722 rows × 7 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 72
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:14:44.368374Z",
     "start_time": "2025-05-14T01:14:44.189884Z"
    }
   },
   "cell_type": "code",
   "source": [
    "test_buys['label'] = 1\n",
    "test_buys = test_buys[['user_id', 'item_id', 'label']]\n",
    "\n",
    "# 合并标签\n",
    "train_df = features.merge(test_buys, on=['user_id', 'item_id'], how='left')\n",
    "train_df['label'] = train_df['label'].fillna(0).astype(int)\n",
    "train_df"
   ],
   "id": "b2090612e2ce761e",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "          user_id    item_id  interact_count  last_interact_day  has_browsed  \\\n",
       "0             492    2316002               3                  9            1   \n",
       "1             492   31040941               2                 15            1   \n",
       "2             492   50834828               2                  9            1   \n",
       "3             492   65264993               2                  9            1   \n",
       "4             492   76093985               1                 18            1   \n",
       "...           ...        ...             ...                ...          ...   \n",
       "803591  142442955  260934112               2                 15            1   \n",
       "803592  142442955  273532679               2                 15            1   \n",
       "803593  142442955  325938147               3                 15            1   \n",
       "803594  142442955  364397686               2                 15            1   \n",
       "803595  142442955  386680968               2                 15            1   \n",
       "\n",
       "        has_favorited  has_carted  has_bought  user_total_actions  \\\n",
       "0                   0           0           0                  36   \n",
       "1                   0           0           0                  36   \n",
       "2                   0           0           0                  36   \n",
       "3                   0           0           0                  36   \n",
       "4                   0           0           0                  36   \n",
       "...               ...         ...         ...                 ...   \n",
       "803591              0           0           0                  52   \n",
       "803592              0           0           0                  52   \n",
       "803593              0           0           0                  52   \n",
       "803594              0           0           0                  52   \n",
       "803595              0           0           0                  52   \n",
       "\n",
       "        user_buy_rate  item_popularity  item_buy_rate  \\\n",
       "0                 0.0                3       0.000000   \n",
       "1                 0.0               75       0.013333   \n",
       "2                 0.0                2       0.000000   \n",
       "3                 0.0                2       0.000000   \n",
       "4                 0.0               87       0.000000   \n",
       "...               ...              ...            ...   \n",
       "803591            0.0                2       0.000000   \n",
       "803592            0.0               11       0.000000   \n",
       "803593            0.0               46       0.043478   \n",
       "803594            0.0                5       0.000000   \n",
       "803595            0.0                2       0.000000   \n",
       "\n",
       "        days_since_last_interact  time_decay  label  \n",
       "0                             21    0.322581      0  \n",
       "1                             15    0.400000      0  \n",
       "2                             21    0.322581      0  \n",
       "3                             21    0.322581      0  \n",
       "4                             12    0.454545      0  \n",
       "...                          ...         ...    ...  \n",
       "803591                        15    0.400000      0  \n",
       "803592                        15    0.400000      0  \n",
       "803593                        15    0.400000      0  \n",
       "803594                        15    0.400000      0  \n",
       "803595                        15    0.400000      0  \n",
       "\n",
       "[803596 rows x 15 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>interact_count</th>\n",
       "      <th>last_interact_day</th>\n",
       "      <th>has_browsed</th>\n",
       "      <th>has_favorited</th>\n",
       "      <th>has_carted</th>\n",
       "      <th>has_bought</th>\n",
       "      <th>user_total_actions</th>\n",
       "      <th>user_buy_rate</th>\n",
       "      <th>item_popularity</th>\n",
       "      <th>item_buy_rate</th>\n",
       "      <th>days_since_last_interact</th>\n",
       "      <th>time_decay</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>492</td>\n",
       "      <td>2316002</td>\n",
       "      <td>3</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>21</td>\n",
       "      <td>0.322581</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>492</td>\n",
       "      <td>31040941</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>75</td>\n",
       "      <td>0.013333</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>492</td>\n",
       "      <td>50834828</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>21</td>\n",
       "      <td>0.322581</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>492</td>\n",
       "      <td>65264993</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>21</td>\n",
       "      <td>0.322581</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>492</td>\n",
       "      <td>76093985</td>\n",
       "      <td>1</td>\n",
       "      <td>18</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>36</td>\n",
       "      <td>0.0</td>\n",
       "      <td>87</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>12</td>\n",
       "      <td>0.454545</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>803591</th>\n",
       "      <td>142442955</td>\n",
       "      <td>260934112</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>803592</th>\n",
       "      <td>142442955</td>\n",
       "      <td>273532679</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>11</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>803593</th>\n",
       "      <td>142442955</td>\n",
       "      <td>325938147</td>\n",
       "      <td>3</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>46</td>\n",
       "      <td>0.043478</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>803594</th>\n",
       "      <td>142442955</td>\n",
       "      <td>364397686</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>5</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>803595</th>\n",
       "      <td>142442955</td>\n",
       "      <td>386680968</td>\n",
       "      <td>2</td>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>52</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15</td>\n",
       "      <td>0.400000</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>803596 rows × 15 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 73
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:15:34.372893Z",
     "start_time": "2025-05-14T01:15:34.048186Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "# 特征选择和训练集划分\n",
    "feature_cols = ['interact_count', 'last_interact_day', 'has_browsed', \n",
    "                'has_favorited', 'has_carted', 'user_total_actions', \n",
    "                'user_buy_rate', 'item_popularity', 'item_buy_rate', \n",
    "                'time_decay']\n",
    "\n",
    "X = train_df[feature_cols]\n",
    "y = train_df['label']\n",
    "\n",
    "\n",
    "# 标准化特征\n",
    "scaler = StandardScaler()\n",
    "X_scaled = scaler.fit_transform(X)\n",
    "\n",
    "# 划分训练验证集\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X_scaled, \n",
    "    y, \n",
    "    test_size=0.2, \n",
    "    random_state=42,\n",
    "    stratify=y # 均衡采样,按y的分部分层抽样\n",
    ")\n",
    "X_train.shape, X_test.shape, y_train.shape, y_test.shape"
   ],
   "id": "6aec3e97e40087f9",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((642876, 10), (160720, 10), (642876,), (160720,))"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 74
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "1.4、数据建模 （训练逻辑回归模型）"
   ],
   "id": "cb8198ba41c6decc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:17:19.722562Z",
     "start_time": "2025-05-14T01:17:18.531481Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "# 初始化并训练逻辑回归模型\n",
    "lr_model = LogisticRegression(\n",
    "    class_weight='balanced',  # 处理类别不平衡\n",
    "    max_iter=1000,\n",
    "    random_state=42,\n",
    "    solver='liblinear'\n",
    ")\n",
    "lr_model.fit(X_train, y_train)"
   ],
   "id": "52f467c580b18a8f",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LogisticRegression(class_weight='balanced', max_iter=1000, random_state=42,\n",
       "                   solver='liblinear')"
      ],
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LogisticRegression(class_weight=&#x27;balanced&#x27;, max_iter=1000, random_state=42,\n",
       "                   solver=&#x27;liblinear&#x27;)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>LogisticRegression</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.linear_model.LogisticRegression.html\">?<span>Documentation for LogisticRegression</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>LogisticRegression(class_weight=&#x27;balanced&#x27;, max_iter=1000, random_state=42,\n",
       "                   solver=&#x27;liblinear&#x27;)</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 76
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:20:34.105458Z",
     "start_time": "2025-05-14T01:20:34.083335Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 评估模型\n",
    "from sklearn.metrics import f1_score\n",
    "\n",
    "y_pred = lr_model.predict(X_test)\n",
    "print(f\"验证集F1分数: {f1_score(y_test, y_pred):.4f}\")"
   ],
   "id": "b6a0aaaa43e66f22",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "验证集F1分数: 0.6897\n"
     ]
    }
   ],
   "execution_count": 78
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "生成预测结果"
   ],
   "id": "2c1c740a2f948d13"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:34:42.906614Z",
     "start_time": "2025-05-14T01:34:42.825546Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 为所有用户-商品对生成预测(概率)\n",
    "user_item_pairs = features[['user_id', 'item_id']].copy()\n",
    "X_all = scaler.transform(features[feature_cols])\n",
    "user_item_pairs['prob'] = lr_model.predict_proba(X_all)[:, 1]\n",
    "user_item_pairs"
   ],
   "id": "c321e37c82a6e9da",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "          user_id    item_id      prob\n",
       "0             492    2316002  0.005833\n",
       "1             492   31040941  0.010060\n",
       "2             492   50834828  0.003076\n",
       "3             492   65264993  0.003076\n",
       "4             492   76093985  0.002244\n",
       "...           ...        ...       ...\n",
       "801332  142442955  260934112  0.003148\n",
       "801333  142442955  273532679  0.003245\n",
       "801334  142442955  325938147  0.119382\n",
       "801335  142442955  364397686  0.003180\n",
       "801336  142442955  386680968  0.003148\n",
       "\n",
       "[801337 rows x 3 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>prob</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>492</td>\n",
       "      <td>2316002</td>\n",
       "      <td>0.005833</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>492</td>\n",
       "      <td>31040941</td>\n",
       "      <td>0.010060</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>492</td>\n",
       "      <td>50834828</td>\n",
       "      <td>0.003076</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>492</td>\n",
       "      <td>65264993</td>\n",
       "      <td>0.003076</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>492</td>\n",
       "      <td>76093985</td>\n",
       "      <td>0.002244</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801332</th>\n",
       "      <td>142442955</td>\n",
       "      <td>260934112</td>\n",
       "      <td>0.003148</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801333</th>\n",
       "      <td>142442955</td>\n",
       "      <td>273532679</td>\n",
       "      <td>0.003245</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801334</th>\n",
       "      <td>142442955</td>\n",
       "      <td>325938147</td>\n",
       "      <td>0.119382</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801335</th>\n",
       "      <td>142442955</td>\n",
       "      <td>364397686</td>\n",
       "      <td>0.003180</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801336</th>\n",
       "      <td>142442955</td>\n",
       "      <td>386680968</td>\n",
       "      <td>0.003148</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>801337 rows × 3 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 79
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:35:30.415154Z",
     "start_time": "2025-05-14T01:35:30.149420Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 选择每个用户最可能购买的10个商品\n",
    "recommendations = (user_item_pairs.sort_values(['user_id', 'prob'], ascending=False).groupby('user_id').head(10))\n",
    "\n",
    "recommendations"
   ],
   "id": "ef09151ab054ef75",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "          user_id    item_id      prob\n",
       "801331  142442955  222892402  0.674089\n",
       "801334  142442955  325938147  0.119382\n",
       "801321  142442955   88908007  0.016815\n",
       "801328  142442955  207322826  0.016815\n",
       "801330  142442955  222401327  0.016815\n",
       "...           ...        ...       ...\n",
       "11            492  231130796  0.005833\n",
       "15            492  374520755  0.003661\n",
       "5             492  110036513  0.003332\n",
       "8             492  178412255  0.003276\n",
       "2             492   50834828  0.003076\n",
       "\n",
       "[163938 rows x 3 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "      <th>prob</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>801331</th>\n",
       "      <td>142442955</td>\n",
       "      <td>222892402</td>\n",
       "      <td>0.674089</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801334</th>\n",
       "      <td>142442955</td>\n",
       "      <td>325938147</td>\n",
       "      <td>0.119382</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801321</th>\n",
       "      <td>142442955</td>\n",
       "      <td>88908007</td>\n",
       "      <td>0.016815</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801328</th>\n",
       "      <td>142442955</td>\n",
       "      <td>207322826</td>\n",
       "      <td>0.016815</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801330</th>\n",
       "      <td>142442955</td>\n",
       "      <td>222401327</td>\n",
       "      <td>0.016815</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>492</td>\n",
       "      <td>231130796</td>\n",
       "      <td>0.005833</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>492</td>\n",
       "      <td>374520755</td>\n",
       "      <td>0.003661</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>492</td>\n",
       "      <td>110036513</td>\n",
       "      <td>0.003332</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>492</td>\n",
       "      <td>178412255</td>\n",
       "      <td>0.003276</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>492</td>\n",
       "      <td>50834828</td>\n",
       "      <td>0.003076</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>163938 rows × 3 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 80
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:35:41.183917Z",
     "start_time": "2025-05-14T01:35:41.101820Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 确保只包含目标商品\n",
    "final_recommend = recommendations[recommendations['item_id'].isin(target_item_set)]\n",
    "final_recommend = final_recommend[['user_id', 'item_id']].drop_duplicates()\n",
    "\n",
    "final_recommend"
   ],
   "id": "d957572ee7fa8cce",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "          user_id    item_id\n",
       "801331  142442955  222892402\n",
       "801334  142442955  325938147\n",
       "801321  142442955   88908007\n",
       "801328  142442955  207322826\n",
       "801330  142442955  222401327\n",
       "...           ...        ...\n",
       "11            492  231130796\n",
       "15            492  374520755\n",
       "5             492  110036513\n",
       "8             492  178412255\n",
       "2             492   50834828\n",
       "\n",
       "[163938 rows x 2 columns]"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>item_id</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>801331</th>\n",
       "      <td>142442955</td>\n",
       "      <td>222892402</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801334</th>\n",
       "      <td>142442955</td>\n",
       "      <td>325938147</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801321</th>\n",
       "      <td>142442955</td>\n",
       "      <td>88908007</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801328</th>\n",
       "      <td>142442955</td>\n",
       "      <td>207322826</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>801330</th>\n",
       "      <td>142442955</td>\n",
       "      <td>222401327</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>492</td>\n",
       "      <td>231130796</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>492</td>\n",
       "      <td>374520755</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>492</td>\n",
       "      <td>110036513</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>492</td>\n",
       "      <td>178412255</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>492</td>\n",
       "      <td>50834828</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>163938 rows × 2 columns</p>\n",
       "</div>"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 81
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T01:35:57.088996Z",
     "start_time": "2025-05-14T01:35:57.004615Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 保存结果\n",
    "final_recommend.to_csv('tianchi_mobile_recommendation_predict.csv', index=False, header=False)\n",
    "print(f\"生成推荐结果，共{len(final_recommend)}条记录\")"
   ],
   "id": "4619881b10a1d370",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "生成推荐结果，共163938条记录\n"
     ]
    }
   ],
   "execution_count": 82
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-14T00:11:05.462328Z",
     "start_time": "2025-05-14T00:11:05.458340Z"
    }
   },
   "cell_type": "code",
   "source": [
    "'''\n",
    "在真实的业务场景下，我们往往需要对所有商品的一个子集构建个性化推荐模型。在完成这件任务的过程中，\n",
    "我们不仅需要利用用户在这个商品子集上的行为数据，往往还需要利用更丰富的用户行为数据。定义如下的符号：\n",
    "U——用户集合\n",
    "I——商品全集\n",
    "P——商品子集，P ⊆ I\n",
    "D——用户对商品全集的行为数据集合\n",
    "那么我们的目标是利用D来构造U中用户对P中商品的推荐模型。\n",
    "\n",
    "采用前面一个月的用户-行为数据，预测在接下来的一天用户在指定商品子集上的购买情况(购买/不购买)\n",
    "\n",
    "'''"
   ],
   "id": "456457d577a27d08",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\n在真实的业务场景下，我们往往需要对所有商品的一个子集构建个性化推荐模型。在完成这件任务的过程中，\\n我们不仅需要利用用户在这个商品子集上的行为数据，往往还需要利用更丰富的用户行为数据。定义如下的符号：\\nU——用户集合\\nI——商品全集\\nP——商品子集，P ⊆ I\\nD——用户对商品全集的行为数据集合\\n那么我们的目标是利用D来构造U中用户对P中商品的推荐模型。\\n\\n采用前面一个月的用户-行为数据，预测在接下来的一天用户在指定商品子集上的购买情况(购买/不购买)\\n\\n'"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 36
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
